/**
 *文件名称：
 *
 *文件日期：
 *
 *文件描述：
 *
 *文件版本：V1.0
 *
 */

#ifndef PROTOCOL_H
#define PROTOCOL_H

/* 头文件包含区	*/
#include "stdint.h"

// <<< Use Configuration Wizard in Context Menu >>>
#define NO_KNOW 0
#define NB 1
#define CAT1 2
#define NB_ONENET 3
// <o> Device Type <0=> NO_KNOW <1=> NB <2=> CAT1 <3=> NB_ONENET
#define PROJECT_TYPEDEF 2

#define SINGLE_LED 0 //单灯
#define DOUBLE_LED 1 //双灯
// <o> Channel Number <0=> Single Led <1=> Double Led
#define LED_TYPEDEF 0

#define NORMAL_STRUCTURE 0 //普通结构
#define NEMA_STRUCTURE 1 //NEMA结构
// <o> Device structure <0=> normal structure <1=> NEMA structure
#define LED_STRUCTURE 0

#define DEFAULT_IP 0
#define WUHAN_PROTOCOL 1
#define ELSE_IP 2
// <o> Public Protocol Ip <0=> Default IP <1=> WuHan Project <2=> Else Ip
// <i> default ip is mqtt.ctwing.cn
// <i> WuHan Project is dong xi hu Project
// <i> Else Ip is xiao yun kong
#define IP_PUBLIC 0
// <h> Else Configuration
#define CTRL_LAMP_CH 2 //可支持的控制路灯回路数
// <o> Scene Timer Number <0-16>
#define SCENE_TIME_NUM 8 //可支持的策略时间表数量
// <o> Flash Data Buffer Size <0-256>
#define FLASH_DATA_BUF 100
#define LAMP_CHANGE //路灯渐变由亮到灭再到亮
// <o> Data_Info Max Size <0-5>
#define PROTOCOL_REG_NUM 4 //每包数据可支持的最大寄存器个数

// <o> Is Supported Public Protocol <0=> NO_Support <1=> Support
#define PROJECT_NUM 0
// </h>
// <<< end of configuration section >>>
#if (PROJECT_NUM == 1)
#define PUBLIC_PROTOCOL
#endif
#define LEAST_POWER 18
#if (LED_TYPEDEF == SINGLE_LED) 
#if (PROJECT_TYPEDEF == NB)
  #define DEVICE_TYPEDEF  0x01010101
#elif (PROJECT_TYPEDEF == CAT1)
  #define DEVICE_TYPEDEF  0x02010002
  #define  TIMESCOMPARE 7
#elif (PROJECT_TYPEDEF == NB_ONENET)
  #define DEVICE_TYPEDEF  0x01010200
#endif
#endif

#if (PROJECT_TYPEDEF == NB)
#define MODE_ID "NB-II"
#elif (PROJECT_TYPEDEF == CAT1)
#define MODE_ID "CAT1-II"
#elif (PROJECT_TYPEDEF == NB_ONENET)
#define MODE_ID "NB-NOENET-II"
#else
#error "设备未定义"
#endif
#define CAT1_NETWORK_TIME
/* 类型声明区 */
#pragma pack(1)
typedef struct
{
  uint8_t light;
  uint8_t sw;
} lampStruct;

typedef struct
{
  uint8_t crc16_h;
  uint8_t crc16_l;
} crc16Struct;

typedef struct
{
  uint8_t Temp_bit : 1;
  uint8_t I_bit : 1;
  uint8_t U_bit : 1;
  uint8_t Titl_bit : 1;
  uint8_t LeakCurrent_bit : 1; //漏电
  uint8_t I2_bit : 1;
  uint8_t Lamp1_bit : 1;
  uint8_t Lamp2_bit : 1;       //电源损坏
  uint8_t lowU_bit : 1;
  uint8_t power_bit : 1;
  uint8_t power_bit2 : 1;
  uint8_t lamp1Dimming_bit : 1; //调光异常
  uint8_t lamp2Dimming_bit : 1;
  uint8_t low_Temp_bit : 1;
  uint8_t Lamp_failure : 1;    //灯具损坏
  uint8_t Lamp2_failure : 1;
} last_alarm_bit;

typedef struct
{
  uint8_t start : 1;
  uint8_t ati : 1;
  uint8_t imei : 1;
  uint8_t iccid : 1;
  uint8_t csq : 1;
  uint8_t creg : 1;
  uint8_t cgatt : 1;
  uint8_t uplink : 1;
  uint8_t reserve_0;
} test_bit;

//读写结构体
typedef struct
{
  uint16_t year_mon;             /* 1003 年月 */
  uint16_t day_hour;             /* 1004 日时 */
  uint16_t min_sec;              /* 1005 分秒 */
  uint16_t baud;                 /* 1006 波特率 */
  uint16_t ota_start_flag;       /* 1007 ota开始标志 */
  uint16_t ota_flag;             /* 1008 ota标志 */
  lampStruct lamp[CTRL_LAMP_CH]; /* 1009 路灯开关和亮度控制 */
  uint16_t reserve[11];          /* 保留 */
	uint16_t lamp_init_status;     /* 1016 灯具初始状态 */
  uint16_t restart_count;        /* 1017 重启次数 */
#if (PROJECT_TYPEDEF == NB || PROJECT_TYPEDEF == NB_ONENET)
  uint16_t OTA_new_version;
  uint16_t reset_process;
  uint16_t reserve_3[1]; //保留
#elif(PROJECT_TYPEDEF == CAT1)
  uint16_t reserve_3[3]; //保留
#endif
  uint16_t cpmpare_delta;
  uint16_t cmp_xyz_reset;//101C
  uint16_t moso_max_light;					/* 茂硕电源最大功率亮度检测  3061*/
  uint16_t reserve_4[7]; //保留 101D 101E 101F 1010 1011 1012 1013 1014 
  uint16_t device_type; //1025   1：标准版 2:专业版 3:NEMA结构 0：未知
  #if(PROJECT_TYPEDEF == CAT1)
  uint16_t reserve_5[2]; //保留
  #else
  uint16_t reserve_5[4]; //保留
  #endif
} RW_struct;

//只读结构体
typedef struct
{
  last_alarm_bit alarm;         /* 3001 告警标志 */
  int16_t csq;                 /* 3002 信号强度 */
  uint16_t v_hz;                /* 3003 电压频率 */
  int16_t temp;                 /* 3004 模块温度 */
  uint16_t v;                   /* 3005 当前电压有效值 */
  uint16_t i1;                  /* 3006 通道1当前电流有效值 */
  uint16_t p1;                  /* 3007 通道1当前有功功率 */
  uint32_t e1;                  /* 3008 通道1有功电能*/
  uint16_t p1_factor;           /* 300A 通道1功率因数 */
  uint16_t i2;                  /* 300B 通道2当前电流有效值 */
  uint16_t p2;                  /* 300C 通道2当前有功功率 */
  uint32_t e2;                  /* 300D 通道2有功电能 */
  uint16_t p2_factor;           /* 300F 通道2功率因数 */
  uint16_t lamp_xy_offset;      /* 3010 灯杆x,y偏移量 */
  uint16_t lamp_z_offset;       /* 3011 灯杆z偏移量 */
  uint32_t module_run_time;     /* 3012 模块上电时长 */
  uint32_t module_all_run_time; /* 3014 模块累计工作时长 */
  uint32_t lamp1_all_run_time;  /* 3016 通道1灯具累计工作时长 */
  uint32_t lamp1_run_time;      /* 3018 通道1灯具工作时长 */
  uint32_t lamp2_all_run_time;  /* 301A 通道2灯具累计工作时长 */
  uint32_t lamp2_run_time;      /* 301C 通道2灯具工作时长 */
  uint8_t module_id[10];        /* 301E 出厂序列号 */
  uint8_t iccid[10];            /* 3023 ICCID卡号 */
  uint16_t v_alarm_count;       /* 3028 过压告警次数 */
  uint16_t i_alarm_count;       /* 3029 电流告警次数 */
  uint16_t temp_alarm_count;    /* 302A 温度告警次数 */
  uint16_t lamp_current_xy;     /* 302B 灯杆x,y轴信息 */
  uint16_t lamp_current_z;      /* 302C 灯杆Z轴信息 */
  uint16_t leak_i;              /* 302D 当前漏电数值 */
  uint16_t software_version;    /* 302E 软件版本号 */
  uint16_t sunset;              /* 302F 日出时分 */
  uint16_t sunrise;             /* 3030 日落时分 */
  uint16_t scene_sum;           /* 3031 策略定时数目 */
  uint16_t reserve[15];         /* 保留 */
  uint16_t run_state;           /* 3041 当前的运行状态，1位在app区运行，0为在boot区运行 */
  uint8_t hardware_version[30]; /* 3042 硬件版本号 */
  uint16_t titl_alarm_cnt;      /* 3051 倾斜告警次数 */
  uint16_t lc_alarm_cnt;        /* 3052 漏电告警次数 */
  uint16_t lamp1_alarm_cnt;     /* 3053 灯具1损坏告警次数 */
  uint16_t lamp2_alarm_cnt;     /* 3054 灯具2损坏告警次数*/
  uint16_t lowU_alarm_cnt;      /* 3055 欠压告警次数 */
  uint16_t power_alarm_cnt;     /* 3056 过载告警次数 */
  test_bit wireless_run_state;  /*3057 模组当前运行状态（上位机测试时使用）*/
  uint16_t signal_quality;      /*3058*/
  int16_t sinr;                  /*3059*/
  uint16_t low_temp_alarm_count; /* 305A */
  uint16_t powerOn_year_mon;    /*305B */
  uint16_t powerOn_day_hour;    /* 305C 日时 */
  uint16_t powerOn_min_sec;   /* 305D 分秒 */
  uint16_t lamp_hundred;        /* 高位灯具百分之百时亮度，低位灯具百分之10时亮度 305E*/
  uint16_t upgrade_mark;        /* 高位灯具百分之百时亮度，低位灯具百分之10时亮度 305F*/
  uint16_t moso_max_light1; 		/* 茂硕电源最大亮度pwm 3060 */
} R_struct;

typedef struct
{

  uint16_t v_alarm_max;               /* 3200 最大过压值 */
  uint32_t v_alarm_max_time;          /* 3201 最大过压值发生时间 */
  uint16_t v_alarm_max_last;          /* 3203 最近一次过压值 */
  uint32_t v_alarm_max_last_time;     /* 3204 最近一次过压值发生时间 */

  uint16_t v_alarm_least;               /* 3206 最小电压值 */
  uint32_t v_alarm_least_time;          /* 3207 最小电压值发生时间 */
  uint16_t v_alarm_least_last;          /* 3209 最近一次欠压值 */
  uint32_t v_alarm_least_last_time;     /* 320A 最近一次欠压值发生时间 */

  uint16_t i_alarm_max;               /* 320C 最大过流值 */
  uint32_t i_alarm_max_time;          /* 320D 最大过流值发生时间 */
  uint16_t i_alarm_max_last;          /* 320F 最近一次过流值 */
  uint32_t i_alarm_max_last_time;     /* 3210 最近一次过流值发生时间 */

  uint16_t p_alarm_max;               /* 3212 最大过载值 */
  uint16_t p_u_alarm_max;             /* 3213 最大过载时电压值 */
  uint16_t p_i_alarm_max;             /* 3214 最大过载时电流值 */
  uint32_t p_alarm_max_time;          /* 3215 最大过载值发生时间 */
  uint16_t p_alarm_max_last;          /* 3217 最近一次过载值 */
  uint16_t p_u_alarm_max_last;        /* 3218 最近一次过载值 */
  uint16_t p_i_alarm_max_last;        /* 3219 最近一次过载值 */
  uint32_t p_alarm_max_last_time;     /* 321A 最近一次过载值发生时间 */

  uint32_t lc_alarm_last_time ;      /* 321C 漏电最后发生时间 */

  uint16_t titl_alarm_max;               /* 321E 最大过流值 */
  uint32_t titl_alarm_max_time;          /* 321F 最大过流值发生时间 */
  uint16_t titl_alarm_max_last;          /* 3221 最近一次过流值 */
  uint32_t titl_alarm_max_last_time;     /* 3222 最近一次过流值发生时间 */

  uint16_t high_temp_alarm_max;               /* 3224 最大温度值 */
  uint32_t high_temp_alarm_max_time;          /* 3225 最大温度值发生时间 */
  uint16_t high_temp_alarm_max_last;          /* 3227 最近一次过温值 */
  uint32_t high_temp_alarm_max_last_time;     /* 3228 最近一次过温值发生时间 */

  int16_t low_temp_alarm_max;               /* 322A 最低温度值 */
  uint32_t low_temp_alarm_max_time;          /* 322B 最低温度值发生时间 */
  int16_t low_temp_alarm_max_last;          /* 322D 最近一次低温值 */
  uint32_t low_temp_alarm_max_last_time;     /* 322E 最近一次低温值发生时间 */

  uint16_t lamp2_i_alarm_max;               /* 3230 最大过流值 */
  uint32_t lamp2_i_alarm_max_time;          /* 3231 最大过流值发生时间 */
  uint16_t lamp2_i_alarm_max_last;          /* 3233 最近一次过流值 */
  uint32_t lamp2_i_alarm_max_last_time;     /* 3234 最近一次过流值发生时间 */

  uint16_t lamp2_p_alarm_max;               /* 3236 最大过载值 */
  uint16_t lamp2_p_u_alarm_max;             /* 3237 最大过载时电压值 */
  uint16_t lamp2_p_i_alarm_max;             /* 3238 最大过载时电流值 */
  uint32_t lamp2_p_alarm_max_time;          /* 3239 最大过载值发生时间 */
  uint16_t lamp2_p_alarm_max_last;          /* 323B 最近一次过载值 */
  uint16_t lamp2_p_u_alarm_max_last;        /* 323C 最近一次过载值 */
  uint16_t lamp2_p_i_alarm_max_last;        /* 323D 最近一次过载值 */
  uint32_t lamp2_p_alarm_max_last_time;     /* 323E 最近一次过载值发生时间 */

}R_ALARM_struct;

typedef struct
{
  uint16_t ten_percent_power;
  uint16_t Twenty_percent_power;
  uint16_t thirty_percent_power;
  uint16_t forty_percent_power;
  uint16_t fifty_percent_power;
  uint16_t sixty_percent_power;
  uint16_t seventy_percent_power;
  uint16_t eighty_percent_power;
  uint16_t ninety_percent_power;
  uint16_t hundred_percent_power;
}POWER_VALUE;

//场景结构体
typedef struct
{
  uint16_t scene_id;
  uint8_t scene_type;
  uint8_t start_year;
  uint8_t start_mon;
  uint8_t start_date;
  uint8_t end_year;
  uint8_t end_mon;
  uint8_t end_date;
  uint8_t time_type;
  uint8_t time_ctrl_ch_num;
  lampStruct ctrl_buf[CTRL_LAMP_CH];
  uint8_t hour;
  uint8_t min;
  uint8_t sec;
} scene_struct;

typedef struct
{
  scene_struct lastScene;
  scene_struct nextScene;
  uint16_t lastSceneSeek;
  uint16_t nextSceneSeek;
} compare_Struct;

//只写结构体
typedef struct
{
  uint16_t v_alarm_set;               /* 2001 报警电压 */
  uint16_t i_alarm_set;               /* 2002 报警电流 */
  int16_t  temp_alarm_set;            /* 2003 高温报警温度 */
  uint16_t data_tx_time;              /* 2004 主动上报时间间隔 */
  uint16_t lowU_set;                  /* 2005 欠压告警阈值 */
  uint16_t power_set;                 /* 2006 过载告警阈值 */
  uint16_t restart;                   /* 2007 复位 */
  uint16_t all_param_clear;           /* 2008 所以参数清楚命令 */
  uint16_t module_time_clear;         /* 2009 模块时长清0使能 */
  uint16_t lamp_time_clear;           /* 200A 灯具时长清0使能 */
  uint16_t ota_sum_len;               /* 200B 接收的固件包总长度 */
  uint16_t software_len;              /* 200C 固件长度 */
  uint16_t scene_clear;               /* 200D 场景和时间表全部清除使能 */
  uint16_t lamp_cpmpare_xy;           /* 200E 灯杆x,y轴绝对值 */
  uint16_t lamp_cpmpare_z;            /* 200F 灯杆Z轴绝对值，角度值 */
  uint16_t ip_h;                      /* 2010 服务器IP前两个 */
  uint16_t ip_l;                      /* 2011 服务器IP后两个 */
  uint16_t ip_port;                   /* 2012 端口号 */
  uint16_t leak_current_alarm_set;    /* 2013 漏电告警差值 */
  uint16_t longitude_h;               /* 2014 经度值（东西经，度） */
  uint16_t longitude_l;               /* 2015 经度值（分，秒） */
  uint16_t dimensionality_h;          /* 2016 纬度值（南北纬，度） */
  uint16_t dimensionality_l;          /* 2017 纬度值（分，秒） */
  uint16_t new_versions;              /* 2018 OTA新版本号 */
  uint16_t scene_id;                  /* 2019 策略ID */
  uint16_t moso_alarm_pwm;            /* 201A 无线模块复位操作 */
  uint16_t heartbeat_interval;           /* 201B心跳包间隔时间 */
  uint16_t clear_energy;              /* 201C 清楚电能数据 */
  uint16_t plc_group_number;          /* 201D 组播号 */
  uint8_t scene_CurrentPacketCnt;     /* 201E 当前包序号 */
  uint8_t scene_AllPacketNum;         /* 201F 时间表总包数 */
  uint8_t scene_CurrentTimeTableNum;  /* 2020 当前包时间表数量 */
  uint8_t scene_AllTimeTableNum;      /* 2021 总时间表数量 */
  scene_struct scene[SCENE_TIME_NUM]; /* 2022 场景策略 */
  int16_t low_temp_alarm_set;
  uint16_t detection_dimming;               /* 2069保留3 */
  uint16_t detection_dimming2;               /* 206A保留3 */
  uint16_t flash_data;									/*206B 闪测功能*/
 // uint16_t upgrade_platform;                /*206C 升级来源*/
  uint32_t lamp1_power_on_timestamp;
  uint32_t lamp1_power_off_timestamp;
	uint32_t lamp2_power_on_timestamp;
  uint32_t lamp2_power_off_timestamp;
  uint16_t reserve[4];               /* 保留3 */
} W_struct;

typedef struct
{
  uint16_t rw;
  uint16_t r;
  uint16_t w;
} protocolSize; //记录结构体大小

typedef struct
{
  uint8_t fun_code;                    //功能码
  uint16_t reg_addr[PROTOCOL_REG_NUM]; //寄存器地址
  uint16_t reg_len[PROTOCOL_REG_NUM];  //寄存器长度
  uint8_t *data_buf[PROTOCOL_REG_NUM]; //数据起始地址
  uint16_t data[PROTOCOL_REG_NUM];     //数据
  uint8_t reg_num;                     //寄存器个数
  uint8_t subpackage_cnt;              //记录分包时的分包号
} protocolStruct;

typedef struct
{
  RW_struct RW;
  W_struct W;
  R_struct R;
  crc16Struct crc16;
} regStruct;
#pragma pack()

typedef enum
{
  NONE_OTA,
  IS_OTA,
  OTA_READY,
  OTA_PACKAGE_TX_OK,
  OTA_PACKAGE_RX_OK,
  OTA_FAIL,
  OTA_START,
  OTA_FILE_ERROR
} OTA_FLAG;

extern protocolStruct protocol;
extern RW_struct RW;
extern W_struct W;
extern R_struct R;
extern R_ALARM_struct ALARM_R;
extern POWER_VALUE power;
extern compare_Struct compareStruct;
extern uint32_t timestampTable[SCENE_TIME_NUM];
extern uint16_t flash_data[FLASH_DATA_BUF];
extern regStruct reg;

/* 函数声明区 */
void scene_check(void);
void restart_init(void);
void ota_deal(uint16_t startAddr, uint8_t *otaBuf, uint8_t len);
void fun_code_read(void);
void scene_deal(uint8_t *pSceneBuf);
void fun_code_write(void);
void otaState_check(uint8_t rx_ok_flag);
void fun_code_singleWrite(void);
void protocol_write(uint16_t start_addr, uint8_t *data, uint16_t len);
uint16_t protocol_read(uint16_t start_addr);
void param_init(void);
uint16_t swapUint16_t(uint16_t data);
void swapUint16_t_Plus(uint16_t *indata, uint16_t len);
uint32_t swapUint32_t(uint32_t data);
uint16_t pCharToU16(uint8_t *in_p);
void sort(uint32_t *timeStampBuf, scene_struct *sceneBuf, uint8_t len);
void ota_check(void);
uint8_t start_addr_check(uint16_t startAddr, uint16_t *pU16, uint16_t seek);
void test_test(void);
void check_lamp_sw(uint8_t sw1,uint8_t sw2,  uint32_t timestamp);

#define getU16Data(pChar) \
  pCharToU16((pChar)++);  \
  (pChar)++;
#define GET_NEW_VALUE                 \
  reg.W.scene[i].hour = hourMin / 60; \
  reg.W.scene[i].min = hourMin % 60;  \
  reg.W.scene[i].sec = 0

#endif
